﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <tchar.h>
#include <iostream>
#include <string>
#pragma  warning (disable:4996) 
using namespace std;

HANDLE    hPort = INVALID_HANDLE_VALUE;
HINSTANCE hinstIdLib;
HINSTANCE hinstIcLib;
CVR_InitComm  initComm;
CVR_CloseComm closeComm;
CVR_Authenticate authenticate;
CVR_Read_Content read_Content;
GetPeopleName    getPeopleName;
GetPeopleIDCode  getPeopleIDCode;

rf_init_def rf_init;
rf_exit_def rf_exit;
rf_load_key_def rf_load_key;
rf_card_def rf_card;
rf_read_def rf_read;
rf_authentication_def rf_authentication;
rf_halt_def rf_halt;
rf_beep_def rf_beep;

bool id_dll_loaded = false;
bool is_id_device_ready = false;

int icdev = -1;
bool ic_dll_loaded = false;
bool is_ic_device_ready = false;
uint32_t last_card_id = 0;
uint32_t last_write_card_id = 0;

TCHAR dll_base[MAX_PATH] = { 0 };
unsigned char chKey[16] = { 'P', 'U', 'B', '1', '1', 'A', 0x08, 0x77, 0x8F, 0x69, 'B', 'U', 'P', 'Z', 'Y', 'B' };
unsigned char chKey2[16] = { '8', '8', '8', '8', '8', '8', 0x08, 0x77, 0x8F, 0x69, 'Y', 'T', 'A', '9', '8', 'B' };

unsigned char oldChKey[16] = { '8', '8', '8', '8', '8', '8', 0xFF, 0x07, 0x80, 0x69, '8', '8', '8', '8', '8', '8' };


DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
	0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#define   GUID_CLASS_USB_DEVICE                   GUID_DEVINTERFACE_USB_DEVICE  

DEFINE_GUID(GUID_DEVINTERFACE_USB_HUB,
	0xf18a0e88, 0xc30c, 0x11d0, 0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8);
#define		GUID_CLASS_USB_HUB GUID_DEVINTERFACE_USB_HUB


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	TCHAR szBuffer[MAX_PATH] = { 0 };
	TCHAR termbLib[MAX_PATH] = { 0 };
	TCHAR mwrf32Lib[MAX_PATH] = { 0 };
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:		
		GetModuleFileName(hModule, szBuffer, sizeof(szBuffer) / sizeof(TCHAR) - 1);
		_tcsncpy_s(dll_base, szBuffer, (size_t)(_tcslen(szBuffer) - 18));
		_tcscat_s(termbLib, MAX_PATH, dll_base);
		_tcscat_s(termbLib, MAX_PATH, TEXT("Termb.dll"));
		_tcscat_s(mwrf32Lib, MAX_PATH, dll_base);
		_tcscat_s(mwrf32Lib, MAX_PATH, TEXT("MWRF32.dll"));
		hinstIdLib = LoadLibrary(termbLib);
		if (NULL != hinstIdLib) 
		{
			initComm = (CVR_InitComm)GetProcAddress(hinstIdLib, "CVR_InitComm");
			closeComm = (CVR_CloseComm)GetProcAddress(hinstIdLib, "CVR_CloseComm");
			authenticate = (CVR_Authenticate)GetProcAddress(hinstIdLib, "CVR_Authenticate");
			read_Content = (CVR_Read_Content)GetProcAddress(hinstIdLib, "CVR_Read_Content");
			getPeopleName = (GetPeopleName)GetProcAddress(hinstIdLib, "GetPeopleName");
			getPeopleIDCode = (GetPeopleIDCode)GetProcAddress(hinstIdLib, "GetPeopleIDCode");
			id_dll_loaded = true;
			/*
			if (NULL != initComm && initComm(1001) == 1)
				is_id_device_ready = true;
			*/
		}

		hinstIcLib = LoadLibrary(mwrf32Lib);
		if (NULL != hinstIcLib)
		{
			rf_init = (rf_init_def)GetProcAddress(hinstIcLib, "rf_init");
			rf_exit = (rf_exit_def)GetProcAddress(hinstIcLib, "rf_exit");
			rf_load_key = (rf_load_key_def)GetProcAddress(hinstIcLib, "rf_load_key");
			rf_card = (rf_card_def)GetProcAddress(hinstIcLib, "rf_card");
			rf_read = (rf_read_def)GetProcAddress(hinstIcLib, "rf_read");
			rf_authentication = (rf_authentication_def)GetProcAddress(hinstIcLib, "rf_authentication");
			rf_halt = (rf_halt_def)GetProcAddress(hinstIcLib, "rf_halt");
			rf_beep = (rf_beep_def)GetProcAddress(hinstIcLib, "rf_beep");
			ic_dll_loaded = true;
		}
		break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
		break;
    case DLL_PROCESS_DETACH:
		if (is_id_device_ready && closeComm)
			closeComm();

		if (is_ic_device_ready && rf_exit && icdev >= 0)
			rf_exit(icdev);
		is_id_device_ready = false;
		is_ic_device_ready = false;
		FreeLibrary(hinstIdLib);
		FreeLibrary(hinstIcLib);
		id_dll_loaded = false;
		ic_dll_loaded = false;
        break;
    }
    return TRUE;
}

extern "C" _declspec(dllexport) int ForceReconnect() {
	is_id_device_ready = false;
	is_ic_device_ready = false;

	return 0;
}

extern "C" _declspec(dllexport) int GetIDCardInfo(int port, char *name, int *name_len, char* idcode, int *idcode_len) {
	int rst = 0;
	if (!is_id_device_ready && id_dll_loaded && NULL != initComm) {
		rst = initComm(port);
		switch (rst) {
		case 1:
			is_id_device_ready = true;
			break;
		case 2:
			return YICT_ERROR_DEVICE_PORT;
		default:
			return YICT_ERROR_UNKNOWN;
		}
	}

	if (is_id_device_ready) {
		rst = authenticate();
		switch (rst) {
		case 0:
			return YICT_ERROR_DLL_NOT_FOUND;
		case 1: {
			if (read_Content(1) == 1) {
				getPeopleName(name, name_len);
				getPeopleIDCode(idcode, idcode_len);
				return YICT_SUCC_READ_CARD;
			}
			return YICT_ERROR_READ_CARD;
		}
		case 2:
			return YICT_ERROR_CARD_NOT_FOUND;
		case 3:
			return YICT_ERROR_SELECT_CARD;
		case 4:
			is_id_device_ready = false;
			return YICT_ERROR_DEVICE_PORT;
		default:
			is_id_device_ready = false;
			return YICT_ERROR_UNKNOWN;
		}
	}
	else if (!id_dll_loaded) { return YICT_ERROR_DLL_NOT_FOUND; }
	else { return YICT_ERROR_UNKNOWN; }
}

extern "C" _declspec(dllexport) int GetICCardInfo(char* card_id, int* card_id_len, char* permit_no, int* permit_no_len, char* resu) {
	DWORD ret;
	unsigned char data_info[128];
	string path = "";
	uint32_t card_id_num = 1;
	path += "init comm";
	if (!MT318_InitCommTimeouts())
	{
		path += "，init comm timeout";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		//::MessageBox(NULL, "设置端口超时值", "错误", MB_OK);
		return YICT_ERROR_DEVICE_PORT;
	}
	//寻卡
	path += "FIND M1 CARD";
	ret = MT318_FindM1(data_info);
	if (!ret) {
		path += ", Find M1 operation failed!";
		std::cout << "Find M1 operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		std::cout << "Find M1 success!" << std::endl;
		path += "，Find M1 success!";
	}
	else {
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		path += ", Find M1 failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}

	path += ", MT318_FindMifare1";
	//读取卡序列号
	ret = MT318_FindMifare1(data_info);
	if (!ret) {
		std::cout << "Get M1 card ID operation failed!" << std::endl;
		path += ", Get M1 card ID operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		std::cout << "Get M1 card ID success!" << std::endl;
		path += ", Get M1 card ID success!";
		memcpy(&card_id_num, &data_info[6], 4);
		if (card_id_num == last_card_id) {
			path += ", NOMOVEUP";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_NO_REMOVE_CARD;
		}
		last_card_id = card_id_num;
		auto str_card_id = std::to_string(card_id_num);
		*card_id_len = str_card_id.length();
		memcpy(card_id, str_card_id.c_str(), *card_id_len);
	}
	else {
		std::cout << "Get M1 card ID failed!" << std::endl;
		path += ", Get M1 card ID failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_READ_CARD;
	}

	ret = MT318_CheckKeyA(data_info, 0x01, chKey);
	if (!ret) {
		std::cout << "Check  section 1 keyA operation failed!" << std::endl;
		path += ", Check  section 1 keyA operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check  section 1 keyA success!" << std::endl;
		path += ", Check  section 1 keyA SUCCESS!";
	}
	else {
		ret = MT318_CheckKeyA(data_info, 0x01, oldChKey);
		if (!ret) {
			std::cout << "Check  section 1 keyA operation failed!" << std::endl;
			path += ", Check  section 1 keyA operation failed! ";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check  section 1 keyA success!" << std::endl;
			path += ", Check  section 1 keyA success!";
		}
		else {
			std::cout << "Check  section 1 keyA failed! error num:" << data_info[6] << std::endl;
			path += ",Check  section 1 keyA failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}

	}

	ret = MT318_CheckKeyB(data_info, 0x01, &chKey[10]);
	path += ",MT318_CheckKeyB";
	if (!ret) {
		std::cout << "Check  section 1 keyB operation failed!" << std::endl;
		path += ",Check  section 1 keyB operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check  section 1 keyB success!" << std::endl;
		path += ",Check  section 1 keyB SUCCESS!";
	}
	else {
		ret = MT318_CheckKeyB(data_info, 0x01, &oldChKey[10]);
		path += ",MT318_CheckKeyB!";
		if (!ret) {
			path += ",Check  section 1 keyB operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			std::cout << "Check  section 1 keyB operation failed!" << std::endl;
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check  section 1 keyB success!" << std::endl;
			path += ",Check  section 1 keyB SUCCESS!";
		}
		else {
			std::cout << "Check section 1 keyB failed! error num:" << data_info[6] << std::endl;
			path += "Check section 1 keyB failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}
	}

	ret = MT318_ReadSection(data_info, 0x01, 0x00);//1扇区0块存放permit No.
	path += "MT318_ReadSection";
	if (!ret) {
		std::cout << "Read section 1 permit No. operation failed!" << std::endl;
		path += "Read section 1 permit No. operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[7] == 'Y') {

		memcpy(permit_no, &data_info[8], 16);
		*permit_no_len = strlen(permit_no);
		std::cout << "Read section 1 permit No. success!" << std::endl;
		path += "Read section 1 permit No. success!";
	}
	else {
		std::cout << "Read section 1 permit No. failed! error num:" << data_info[7] << std::endl;
		path += "Read section 1 permit No. failed! error num:";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_READ_CARD;
	}
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	return YICT_SUCC_READ_CARD;
}

								
extern "C" _declspec(dllexport) int GetICCardInfoNotHalt(char* card_id, int* card_id_len, char* permit_no, int* permit_no_len, char* resu) {
	DWORD ret;
	unsigned char data_info[128];
	string path = "";
	uint32_t card_id_num = 0;
	path += "init comm";
	if (!MT318_InitCommTimeouts())
	{
		path += "，init comm timeout";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		//::MessageBox(NULL, "设置端口超时值", "错误", MB_OK);
		return YICT_ERROR_DEVICE_PORT;
	}
	//寻卡
	path += "FIND M1 CARD";
	ret = MT318_FindM1(data_info);
	if (!ret) {
		path += ", Find M1 operation failed!";
		std::cout << "Find M1 operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		std::cout << "Find M1 success!" << std::endl;
		path += "，Find M1 success!";
	}
	else {
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0; 
		last_write_card_id = 0;
		path += ", Find M1 failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}

	path += ", MT318_FindMifare1";
	//读取卡序列号
	ret = MT318_FindMifare1(data_info);
	if (!ret) {
		std::cout << "Get M1 card ID operation failed!" << std::endl;
		path += ", Get M1 card ID operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		std::cout << "Get M1 card ID success!" << std::endl;
		path += ", Get M1 card ID success!";
		memcpy(&card_id_num, &data_info[6], 4);
		// 兼容gate_out_auto业务， 写卡后， 不能再次读卡
		if (card_id_num == last_write_card_id) {
			path += ", NOMOVEUP";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_NO_REMOVE_CARD;
		}
		last_card_id = card_id_num;
		auto str_card_id = std::to_string(card_id_num);
		*card_id_len = str_card_id.length();
		memcpy(card_id, str_card_id.c_str(), *card_id_len);
	}
	else {
		std::cout << "Get M1 card ID failed!" << std::endl;
		path += ", Get M1 card ID failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_READ_CARD;
	}

	ret = MT318_CheckKeyA(data_info, 0x01, chKey);
	if (!ret) {
		std::cout << "Check  section 1 keyA operation failed!" << std::endl;
		path += ", Check  section 1 keyA operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check  section 1 keyA success!" << std::endl;
		path += ", Check  section 1 keyA SUCCESS!";
	}
	else {
		ret = MT318_CheckKeyA(data_info, 0x01, oldChKey);
		if (!ret) {
			std::cout << "Check  section 1 keyA operation failed!" << std::endl;
			path += ", Check  section 1 keyA operation failed! ";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check  section 1 keyA success!" << std::endl;
			path += ", Check  section 1 keyA success!";
		}
		else {
			std::cout << "Check  section 1 keyA failed! error num:" << data_info[6] << std::endl;
			path += ",Check  section 1 keyA failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}

	}

	ret = MT318_CheckKeyB(data_info, 0x01, &chKey[10]);
	path += ",MT318_CheckKeyB";
	if (!ret) {
		std::cout << "Check  section 1 keyB operation failed!" << std::endl;
		path += ",Check  section 1 keyB operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check  section 1 keyB success!" << std::endl;
		path += ",Check  section 1 keyB SUCCESS!";
	}
	else {
		ret = MT318_CheckKeyB(data_info, 0x01, &oldChKey[10]);
		path += ",MT318_CheckKeyB!";
		if (!ret) {
			path += ",Check  section 1 keyB operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			std::cout << "Check  section 1 keyB operation failed!" << std::endl;
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check  section 1 keyB success!" << std::endl;
			path += ",Check  section 1 keyB SUCCESS!";
		}
		else {
			std::cout << "Check section 1 keyB failed! error num:" << data_info[6] << std::endl;
			path += "Check section 1 keyB failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}
	}

	ret = MT318_ReadSection(data_info, 0x01, 0x00);//1扇区0块存放permit No.
	path += "MT318_ReadSection";
	if (!ret) {
		std::cout << "Read section 1 permit No. operation failed!" << std::endl;
		path += "Read section 1 permit No. operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[7] == 'Y') {

		memcpy(permit_no, &data_info[8], 16);
		*permit_no_len = strlen(permit_no);
		std::cout << "Read section 1 permit No. success!" << std::endl;
		path += "Read section 1 permit No. success!";
	}
	else {
		std::cout << "Read section 1 permit No. failed! error num:" << data_info[7] << std::endl;
		path += "Read section 1 permit No. failed! error num:";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_READ_CARD;
	}
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	return YICT_SUCC_READ_CARD;
}
 

extern "C" _declspec(dllexport) int WriteCard(unsigned char* p8, unsigned char* p9, char* resu) {
	DWORD ret;
	unsigned char data_info[128];
	uint32_t card_id_num = 1;
	string path = "test3";
	if (!MT318_InitCommTimeouts())
	{
		//::MessageBox(NULL, "设置端口超时值", "错误", MB_OK);
		return YICT_ERROR_DEVICE_PORT;
	}
	//寻卡
	ret = MT318_FindM1(data_info);
	if (!ret) {
		path += ", Find M1 operation failed!1";
		std::cout << "Find M1 operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		path += ", Find M1 success!";
		std::cout << "Find M1 success!" << std::endl;
	}
	else {
		path += ", Find M1 failed!";
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}

	//读取卡序列号
	path += ", MT318_FindMifare1";
	ret = MT318_FindMifare1(data_info);
	if (!ret) {
		path += ", Find M1 Card No operation failed!";
		std::cout << "Find M1 Card No operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		memcpy(&card_id_num, &data_info[6], 4);
	
		std::cout << "Find M1 success!" << std::endl;
		path += "，Find M1 success!";
	}
	else {
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		path += ", Find M1 failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}


	ret = MT318_CheckKeyA(data_info, 0x02, chKey2);
	if (!ret) {
		std::cout << "Check section 2 keyA operation failed!" << std::endl;
		path += ", Check section 2 keyA operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyA success!" << std::endl;
		path += ", Check section 2 keyA success!";
	}
	else {
		ret = MT318_CheckKeyA(data_info, 0x02, oldChKey);
		if (!ret) {
			std::cout << "Check section 2 keyA operation failed!" << std::endl;
			path += ", Check section 2 keyA operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyA success!" << std::endl;
			path += ", Check section 2 keyA success!";
		}
		else {
			path += ", Check section 2 keyA failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			std::cout << "Check section 2 keyA failed! error num:" << data_info[6] << std::endl;
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	ret = MT318_CheckKeyB(data_info, 0x02, &chKey2[10]);
	if (!ret) {
		std::cout << "Check section 2 keyB operation failed!" << std::endl;
		path += ", Check section 2 keyB operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyB success!" << std::endl;
		path += ", Check section 2 keyB success!";
	}
	else {
		ret = MT318_CheckKeyB(data_info, 0x02, &oldChKey[10]);
		if (!ret) {
			std::cout << "Check section 2 keyB operation failed!" << std::endl;
			path += ", Check section 2 keyB operation failed!1";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyB success!" << std::endl;
			path += ", Check section 2 keyB success!";
		}
		else {
			std::cout << "Check section 2 keyB failed! error num:" << data_info[6] << std::endl;
			path += ", Check section 2 keyB failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}
	}

	ret = MT318_WriteSection(data_info, p8, 0x02, 0x00);
	if (!ret) {
		std::cout << "Write p8 in section 2 operation failed!" << std::endl;
		path += ", Write p8 in section 2 operation failed!" + data_info[6];
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[7] == 'Y') {
		std::cout << "Write p8 in section 2 success!" << std::endl;
		path += ", Write p8 in section 2 success!";
	}
	else {
		std::cout << "Write p8 in section 2 failed! error num:" << data_info[7] << std::endl;
		path += ", Write p8 in section 2 failed! error num:" + data_info[7];
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_WRITE_CARD;
	}

	//寻卡
	ret = MT318_FindM1(data_info);
	if (!ret) {
		path += ", Find M1 operation failed!1";
		std::cout << "Find M1 operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		path += ", Find M1 success!";
		std::cout << "Find M1 success!" << std::endl;
	}
	else {
		path += ", Find M1 failed!";
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}

	//p9
	ret = MT318_CheckKeyA(data_info, 0x02, chKey2);
	if (!ret) {
		std::cout << "Check section 2 keyA operation failed!" << std::endl;
		path += ", Check section 2 keyA operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyA success!" << std::endl;
		path += ", Check section 2 keyA success!";
	}
	else {
		ret = MT318_CheckKeyA(data_info, 0x02, oldChKey);
		if (!ret) {
			path += ", Check section 2 keyA operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			std::cout << "Check section 2 keyA operation failed!" << std::endl;
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyA success!" << std::endl;
			path += ", Check section 2 keyA success!";
		}
		else {
			std::cout << "Check section 2 keyA failed! error num:" << data_info[6] << std::endl;
			path += ", Check section 2 keyA failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	ret = MT318_CheckKeyB(data_info, 0x02, &chKey2[10]);
	if (!ret) {
		std::cout << "Check section 2 keyB operation failed!" << std::endl;
		path += ", Check section 2 keyB operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyB success!" << std::endl;
		path += ", Check section 2 keyB success!";
	}
	else {
		ret = MT318_CheckKeyB(data_info, 0x02, &oldChKey[10]);
		if (!ret) {
			std::cout << "Check section 2 keyB operation failed!" << std::endl;
			path += ", Check section 2 keyB operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyB success!" << std::endl;
			path += ", Check section 2 keyB success!";

		}
		else {
			path += ", Check section 2 keyB failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			std::cout << "Check section 2 keyB failed! error num:" << data_info[6] << std::endl;
			return YICT_ERROR_LOAD_KEYB;
		}
	}

	ret = MT318_WriteSection(data_info, p9, 0x02, 0x01);
	if (!ret) {
		std::cout << "Write p9 in section 2 operation failed!" << std::endl;
		path += ", Write p9 in section 2 operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[7] == 'Y') {
		std::cout << "Write p9 in section 2 success!" << std::endl;
		path += ", Write p9 in section 2 success!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	}
	else {
		std::cout << "Write p9 in section 2 failed! error num:" << data_info[7] << std::endl;
		path += ", Write p9 in section 2 failed! error num:" + data_info[7];
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_WRITE_CARD;
	}
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

	last_write_card_id = card_id_num;
	return YICT_SUCC_WRITE_CARD;
}

extern "C" _declspec(dllexport) int ReadCard(char* p8, int* p8_len, char* p9, int* p9_len, char* resu) {
	DWORD ret;
	unsigned char data_info[128];
	uint32_t card_id_num = 1;
	string path = "";
	if (!MT318_InitCommTimeouts())
	{
		//::MessageBox(NULL, "设置端口超时值", "错误", MB_OK);
		return YICT_ERROR_DEVICE_PORT;
	}
	//寻卡
	ret = MT318_FindM1(data_info);
	if (!ret) {
		path += ", Find M1 operation failed!1";
		std::cout << "Find M1 operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		path += ", Find M1 success!";
		std::cout << "Find M1 success!" << std::endl;
	}
	else {
		path += ", Find M1 failed!";
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}

	//读取卡序列号
	path += ", MT318_FindMifare1";
	ret = MT318_FindMifare1(data_info);
	if (!ret) {
		path += ", Find M1 Card No operation failed!";
		std::cout << "Find M1 Card No operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') { 
		memcpy(&card_id_num, &data_info[6], 4);
		
		std::cout << "Find M1 success!" << std::endl;
		path += "，Find M1 success!";
	}
	else {
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		path += ", Find M1 failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}


	ret = MT318_CheckKeyA(data_info, 0x02, chKey2);
	if (!ret) {
		std::cout << "Check section 2 keyA operation failed!" << std::endl;
		path += ", Check section 2 keyA operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyA success!" << std::endl;
		path += ", Check section 2 keyA success!";
	}
	else {
		ret = MT318_CheckKeyA(data_info, 0x02, oldChKey);
		if (!ret) {
			std::cout << "Check section 2 keyA operation failed!" << std::endl;
			path += ", Check section 2 keyA operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyA success!" << std::endl;
			path += ", Check section 2 keyA success!";
		}
		else {
			path += ", Check section 2 keyA failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			std::cout << "Check section 2 keyA failed! error num:" << data_info[6] << std::endl;
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	ret = MT318_CheckKeyB(data_info, 0x02, &chKey2[10]);
	if (!ret) {
		std::cout << "Check section 2 keyB operation failed!" << std::endl;
		path += ", Check section 2 keyB operation failed!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyB success!" << std::endl;
		path += ", Check section 2 keyB success!";
	}
	else {
		ret = MT318_CheckKeyB(data_info, 0x02, &oldChKey[10]);
		if (!ret) {
			std::cout << "Check section 2 keyB operation failed!" << std::endl;
			path += ", Check section 2 keyB operation failed!1";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyB success!" << std::endl;
			path += ", Check section 2 keyB success!";
		}
		else {
			std::cout << "Check section 2 keyB failed! error num:" << data_info[6] << std::endl;
			path += ", Check section 2 keyB failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}
	}

	ret = MT318_ReadSection(data_info, 0x02, 0x00);//2扇区08块存放的数据
	if (!ret) {
		std::cout << "Read p8 section operation failed!" << std::endl;
		path += ", Read p8 section operation failed!1";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[7] == 'Y') {
		std::cout << "Read p8 section success!" << std::endl;
		memcpy(p8, &data_info[8], 16);
		*p8_len = strlen(p8);
		path += ", Read p8 section success!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	}
	else {
		std::cout << "Read p8 section failed! error num:" << data_info[7] << std::endl;
		path += ", Read p8 section failed! error num:";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_READ_CARD;
	}

	//寻卡
	ret = MT318_FindM1(data_info);
	if (!ret) {
		path += ", Find M1 operation failed!1";
		std::cout << "Find M1 operation failed!" << std::endl;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[5] == 'Y') {
		path += ", Find M1 success!";
		std::cout << "Find M1 success!" << std::endl;
	}
	else {
		path += ", Find M1 failed!";
		std::cout << "Find M1 failed!" << std::endl;
		last_card_id = 0;
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_FIND_M1;
	}
	//p9
	ret = MT318_CheckKeyA(data_info, 0x02, chKey2);
	if (!ret) {
		std::cout << "Check section 2 keyA operation failed!" << std::endl;
		path += ", Check section 2 keyA operation failed!1";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyA success!" << std::endl;
		path += ", Check section 2 keyA success!1";
	}
	else {
		ret = MT318_CheckKeyA(data_info, 0x02, oldChKey);
		if (!ret) {
			std::cout << "Check section 2 keyA operation failed!" << std::endl;
			path += ", Check section 2 keyA operation failed!";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyA success!" << std::endl;
			path += ", Check section 2 keyA success!";
		}
		else {
			std::cout << "Check section 2 keyA failed! error num:" << data_info[6] << std::endl;
			path += ", Check section 2 keyA failed! error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}

	}

	ret = MT318_CheckKeyB(data_info, 0x02, &chKey2[10]);
	if (!ret) {
		std::cout << "Check section 2 keyB operation failed!" << std::endl;
		path += ", Check section 2 keyB operation failed!2";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[6] == 'Y') {
		std::cout << "Check section 2 keyB success!" << std::endl;
		path += ", Check section 2 keyB success!1";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	}
	else {
		ret = MT318_CheckKeyB(data_info, 0x02, &oldChKey[10]);
		if (!ret) {
			std::cout << "Check section 2 keyB operation failed!" << std::endl;
			path += ", Check section 2 keyB operation failed!3";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_UNKNOWN;
		}
		if (data_info[6] == 'Y') {
			std::cout << "Check section 2 keyB success!" << std::endl;
			path += ", Check section 2 keyB success!2";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		}
		else {
			std::cout << "Check section 2 keyB failed! error num:" << data_info[6] << std::endl;
			path += ", Check section 2 keyB failed!2 error num:" + data_info[6];
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}

	}

	ret = MT318_ReadSection(data_info, 0x02, 0x01);//2扇区09块存放的数据
	if (!ret) {
		std::cout << "Read p9 section operation failed!" << std::endl;
		path += ", Read p9 section operation failed!1";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_UNKNOWN;
	}
	if (data_info[7] == 'Y') {
		std::cout << "Read p9 section success!" << std::endl;
		memcpy(p9, &data_info[8], 16);
		*p9_len = strlen(p9);
		path += ", Read p9 section success!";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	}
	else {
		std::cout << "Read p9 section failed! error num:" << data_info[7] << std::endl;
		path += ", Read p9 section failed!3 error num:" + data_info[7];
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_READ_CARD;
	}

	return YICT_SUCC_READ_CARD;
}


extern "C" _declspec(dllexport) void getDevices(char *devs) {
	//LPGUID lpGuid = (LPGUID)&GUID_CLASS_USB_DEVICE;//
	LPGUID lpGuid = (LPGUID)&GUID_CLASS_USB_HUB;//
	int INTERFACE_DETAIL_SIZE = 1024;
	int nCount = 0;
	HDEVINFO info = SetupDiGetClassDevs(lpGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

	//enumerate device information  
	DWORD required_size = 0;
	int i;
	SP_DEVINFO_DATA DeviceInfoData = { sizeof(DeviceInfoData) };

	DWORD DataT;
	DWORD buffersize = 1024;
	DWORD req_bufsize = 0;

	for (i = 0; SetupDiEnumDeviceInfo(info, i, &DeviceInfoData); i++) {
		WCHAR *did = new WCHAR[1024];
		WCHAR *locid = new WCHAR[1024];
		WCHAR *locdesc = new WCHAR[1024];
		//get device description information
		if (!SetupDiGetDeviceInstanceId(info, &DeviceInfoData, (PTSTR)did, buffersize, &req_bufsize))
			continue;
		if (!SetupDiGetDeviceRegistryPropertyW(info, &DeviceInfoData, SPDRP_LOCATION_PATHS, &DataT, (LPBYTE)locid, buffersize, &req_bufsize))
			continue;

		if (!SetupDiGetDeviceRegistryPropertyW(info, &DeviceInfoData, SPDRP_LOCATION_INFORMATION, &DataT, (LPBYTE)locdesc, buffersize, &req_bufsize))
			continue;
	}

	//strcat(devs, )
	SetupDiDestroyDeviceInfoList(info);
}


extern "C" _declspec(dllexport) int MT318_ComOpen(int ComNum)
{
	DWORD baudRate = 9600;
	BYTE byteSize = 8;
	BYTE parity = 0;
	BYTE stopBits = 1;
	LPTSTR lpszPortName = L"COM1";
	switch (ComNum)
	{
	case 1:
		lpszPortName = L"COM1";
		break;
	case 2:
		lpszPortName = L"COM2";
		break;
	case 3:
		lpszPortName = L"COM3";
		break;
	case 4:
		lpszPortName = L"COM4";
		break;
	case 5:
		lpszPortName = L"COM5";
		break;
	case 6:
		lpszPortName = L"COM6";
		break;
	case 7:
		lpszPortName = L"COM7";
		break;
	case 8:
		lpszPortName = L"COM8";
		break;
	case 9:
		lpszPortName = L"COM9";
		break;
	case 10:
		lpszPortName = L"COM10";
		break;
	}

	if (hPort != INVALID_HANDLE_VALUE)
	{
		//::MessageBox(NULL, "hPort != INVALID_HANDLE_VALUE", "错误", MB_OK);
		//return FALSE;
	}

	//打开串口
	hPort = CreateFile((LPTSTR)lpszPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

	//如果打开端口出错, 返回FALSE
	if (hPort == INVALID_HANDLE_VALUE)
	{
		//不能打开端口
		DWORD errNum = GetLastError();
		char buf[256];
		//sprintf(buf, "Unable to open port[%s] errCode[%d]!\n", lpszPortName, errNum);
		//::MessageBox(NULL, buf, "Err code", MB_OK);
		return YICT_ERROR_DEVICE_PORT;
	}

	//指定端口监测的事件集
	SetCommMask(hPort, EV_ERR | EV_RXCHAR | EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY);

	//分配设备缓冲区
	SetupComm(hPort, 512, 32);

	//初始化缓冲区中的信息
	PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR);

	//配置串行端口
	if (!MT318_InitDCB(baudRate, byteSize, parity, stopBits))
	{
		//::MessageBox(NULL, "配置串行端口", "错误", MB_OK);
		return -778;
	}

	//设置端口超时值	
	if (!MT318_InitCommTimeouts())
	{
		//::MessageBox(NULL, "设置端口超时值", "错误", MB_OK);
		return -779;
	}
	//设置端口上指定信号的状态
	// SETDTR: 发送DTR (data-terminal-ready)信号
	// SETRTS: 发送RTS (request-to-send)信号
	EscapeCommFunction(hPort, SETDTR);
	EscapeCommFunction(hPort, SETRTS);

	//clear( hPort );
	PurgeComm(hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	return YICT_SUCC;
}

extern "C" _declspec(dllexport) int MT318_ComClose()
{
	if (hPort != INVALID_HANDLE_VALUE)
	{
		//关闭串口
		CloseHandle(hPort);
		hPort = INVALID_HANDLE_VALUE;

		return 1;
	}
	else
	{
		return 1;
	}
}
BOOL MT318_InitDCB(DWORD baudRate,
	BYTE byteSize,
	BYTE parity,
	BYTE stopBits)
{
	DCB   PortDCB;
	DWORD dwError;

	PortDCB.DCBlength = sizeof(DCB);

	//得到端口的默认设置信息
	GetCommState(hPort, &PortDCB);
	//改变DCB结构设置
	PortDCB.BaudRate = baudRate;		//波特率 
	PortDCB.ByteSize = byteSize;	//每字节的位数 number of bits/byte, 4-8 
	PortDCB.Parity = parity;		//奇偶校验 0-4=no,odd,even,mark,space 
	PortDCB.StopBits = (stopBits == 2) ? 2 : 0;	//每字节一位停止位 0,1,2 = 1, 1.5, 2 
	//根据DCB结构配置端口 
	if (!SetCommState(hPort, &PortDCB))
	{
		MT318_ComClose();
		//不能配置串行端口
		dwError = GetLastError();
		char buf[256];
		//sprintf(buf, "Unable to configure the serial port err:%d\n", dwError);
		//::MessageBox(NULL, buf, "Err code", MB_OK);

		return FALSE;
	}
	return TRUE;
}
BOOL MT318_InitCommTimeouts()
{
	COMMTIMEOUTS CommTimeouts;
	DWORD dwError;

	//得到超时参数
	GetCommTimeouts(hPort, &CommTimeouts);
	//改变COMMTIMEOUTS结构设置

	CommTimeouts.ReadIntervalTimeout = MAXDWORD;
	CommTimeouts.ReadTotalTimeoutMultiplier = 0;
	CommTimeouts.ReadTotalTimeoutConstant = 0;
	CommTimeouts.WriteTotalTimeoutMultiplier = 10;
	CommTimeouts.WriteTotalTimeoutConstant = 1000;

	//设置端口超时值 
	if (!SetCommTimeouts(hPort, &CommTimeouts))
	{
		MT318_ComClose();

		//不能设置超时值
		//printf("Unable to set the time-out parameters\n");
		dwError = GetLastError();
		return FALSE;
	}
	return TRUE;
}
DWORD MT318_ComWrite(TCHAR* buf, DWORD dwCharToWrite)
{
	if (hPort == INVALID_HANDLE_VALUE)
		return 0;
	BOOL  fWriteState;
	DWORD dwBytesWritten;
	//写入数据
	fWriteState = WriteFile(hPort,
		buf,
		dwCharToWrite,//* sizeof(TCHAR),
		&dwBytesWritten,
		NULL);

	if (!fWriteState)
	{
		//不能写数据
		//printf("Can't Write String to Com\n");
		dwBytesWritten = 0;
	}
	return dwBytesWritten;
}
DWORD MT318_ComRead(unsigned char* buf, DWORD size)
{
	if (hPort == INVALID_HANDLE_VALUE)
		return 0;
	//从串口读取数据
	if (!ReadFile(hPort, buf, size, &size, NULL))
	{
		//不能从串口读取数据
		//printf("Error in read from serial port\n");
		size = 0;
	}
	return size;
}
DWORD MT318_ComReadSyn(unsigned char* buf, DWORD wCount, DWORD wWaitTickCount)
{
	//读满 wCound 个字符
	DWORD nReadCount = 0;
	DWORD wTimeBegin = ::GetTickCount();
	while (nReadCount < wCount)
	{
		int count = MT318_ComRead(buf + nReadCount, wCount - nReadCount);
		if (count < 0)
			return -1;

		if (count == 0)
		{
			if (wWaitTickCount > 0 && ::GetTickCount() - wTimeBegin > wWaitTickCount)
				return 0;

			//Sleep(1);
		}
		else
			nReadCount += count;
	}
	return 1;
}

DWORD MT318_GetCardInfo(unsigned char* Data)
{
	DWORD rtn;
	DWORD RtnDataLen = 22;
	unsigned char ReadCardInfo[7];
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x02;
	ReadCardInfo[3] = 0x31;
	ReadCardInfo[4] = 0x40;
	ReadCardInfo[5] = 0x03;
	ReadCardInfo[6] = 0x72;
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		printf("数据正确\n");
		rtn = true;
	}
	else
	{
		rtn = false;
		printf("数据错误\n");
	}
	return rtn;
}
DWORD MT318_DESELECT(unsigned char* Data)
{

	DWORD rtn;
	DWORD RtnDataLen = 8;
	unsigned char ReadCardInfo[7];
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x02;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x42;
	ReadCardInfo[5] = 0x03;
	ReadCardInfo[6] = 0x75;
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		printf("数据正确\n");
		rtn = true;
	}
	else
	{
		rtn = false;
		printf("数据错误\n");
	}
	return rtn;

}
DWORD MT318_FindM1(unsigned char* Data)
{
	DWORD rtn;
	DWORD RtnDataLen = 8;
	unsigned char ReadCardInfo[7];
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x02;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x30;
	ReadCardInfo[5] = 0x03;
	ReadCardInfo[6] = 0x07;
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	//rtn = sizeof(Data) / sizeof(Data[0]);

	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}
	return rtn;
}
DWORD MT318_FindMifare1(unsigned char* Data)
{
	DWORD rtn;
	DWORD RtnDataLen = 12;
	unsigned char ReadCardInfo[7];
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x02;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x31;
	ReadCardInfo[5] = 0x03;
	ReadCardInfo[6] = 0x06;
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	//rtn = sizeof(Data) / sizeof(Data[0]);

	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}
	return rtn;

}
DWORD MT318_CheckKeyA(unsigned char* RetrunData, unsigned char SectionNum, unsigned char* Key)
{
	DWORD rtn = 0;
	DWORD RtnDataLen = 9;
	unsigned char ReadCardInfo[14];
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x09;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x32;
	ReadCardInfo[5] = SectionNum;//扇区号
	memcpy(&ReadCardInfo[6], Key, 6);
	ReadCardInfo[12] = 0x03;

	unsigned char Check = 0;
	for (int i = 0; i < sizeof(ReadCardInfo) - 1; i++) {
		Check = (Check ^ ReadCardInfo[i]);
	}
	ReadCardInfo[13] = Check;
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)RetrunData, RtnDataLen, 100);

	//rtn = sizeof(Data) / sizeof(Data[0]);
	Check = 0;
	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= RetrunData[i];
	}
	if (Check == RetrunData[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}

	return rtn;
}
DWORD MT318_CheckKeyB(unsigned char* RetrunData, unsigned char SectionNum, unsigned char* Key)
{
	DWORD rtn = 0;
	DWORD RtnDataLen = 9;
	unsigned char ReadCardInfo[14];
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x09;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x39;
	ReadCardInfo[5] = SectionNum;//扇区号
	memcpy(&ReadCardInfo[6], Key, 6);
	ReadCardInfo[12] = 0x03;

	unsigned char Check = 0;
	for (int i = 0; i < sizeof(ReadCardInfo) - 1; i++) {
		Check = (Check ^ ReadCardInfo[i]);
	}
	ReadCardInfo[13] = Check;
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)RetrunData, RtnDataLen, 100);

	//rtn = sizeof(Data) / sizeof(Data[0]);
	Check = 0;
	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= RetrunData[i];
	}
	if (Check == RetrunData[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}

	return rtn;
}

DWORD MT318_WriteSection(unsigned char* Data, unsigned char* DataNew, unsigned char SectionNum, unsigned char Num)
{
	DWORD rtn;
	DWORD RtnDataLen = 10;
	unsigned char ReadCardInfo[25] = { 0 };
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x14;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x34;
	ReadCardInfo[5] = SectionNum;
	ReadCardInfo[6] = Num;
	memcpy(&ReadCardInfo[7], DataNew, 16);
	ReadCardInfo[23] = 0x03;
	for (int k = 0; k < 24; k++)
	{
		ReadCardInfo[24] ^= ReadCardInfo[k];
	}
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}
	return rtn;
}

DWORD MT318_ReadSection(unsigned char* Data, unsigned char SectionNum, unsigned char Num)
{
	DWORD rtn;
	DWORD RtnDataLen = 26;
	unsigned char ReadCardInfo[9] = { 0 };
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x04;
	ReadCardInfo[3] = 0x34;
	ReadCardInfo[4] = 0x33;
	ReadCardInfo[5] = SectionNum;
	ReadCardInfo[6] = Num;
	ReadCardInfo[7] = 0x03;
	for (int k = 0; k < 8; k++)
	{
		ReadCardInfo[8] ^= ReadCardInfo[k];
	}
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	if (Data[7] != 'Y') RtnDataLen = 10;


	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}
	return rtn;
}


DWORD MT318_Beep(unsigned char* Data, unsigned char Times, unsigned char Duration_H, unsigned char Duration_L)
{
	DWORD rtn;
	DWORD RtnDataLen = 8;
	unsigned char ReadCardInfo[10] = { 0 };
	unsigned char Check = 0;
	ReadCardInfo[0] = 0x02;
	ReadCardInfo[1] = 0x00;
	ReadCardInfo[2] = 0x05;
	ReadCardInfo[3] = 0x31;
	ReadCardInfo[4] = 0x3e;
	ReadCardInfo[5] = Times;
	ReadCardInfo[6] = Duration_H;
	ReadCardInfo[7] = Duration_L;
	ReadCardInfo[8] = 0x03;
	for (int k = 0; k < 9; k++)
	{
		ReadCardInfo[9] ^= ReadCardInfo[k];
	}
	rtn = MT318_ComWrite((TCHAR*)ReadCardInfo, sizeof(ReadCardInfo));
	MT318_ComReadSyn((unsigned char*)Data, RtnDataLen, 100);

	for (int i = 0; i < RtnDataLen - 1; i++)
	{
		printf("%x ", Data[i + 1]);
		Check ^= Data[i];
	}
	if (Check == Data[RtnDataLen - 1])
	{
		rtn = true;
	}
	else
	{
		rtn = false;
	}
	return rtn;
}


